package com.xhl.demo.controller;

import com.fasterxml.jackson.annotation.JsonView;
import com.xhl.demo.domain.User;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author 徐宏亮
 * @date 2019/1/13 22:28
 * @description
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @ApiOperation("用户查询服务")
    @GetMapping
    @JsonView(User.UserDetailView.class)
    public List<User> query(
            @ApiParam("用户姓名")
            //url中的参数名，是否必须，默认值
            @RequestParam(name = "username", required = false, defaultValue = "user") String username,
            //默认分页信息，第几页，每页大小，排序信息
            //url的形式 page=2&size=17&sort=firstname&sort=lastname,desc
            @PageableDefault(page = 2, size = 17,
                    sort = {"username", "id"}, direction = Sort.Direction.DESC) Pageable pageable) {
        System.out.println(username);
        System.out.println(pageable.getPageSize());
        System.out.println(pageable.getPageNumber());
        System.out.println(pageable.getSort());
        ArrayList<User> userList = new ArrayList<>();
        User user1 = new User();
        user1.setId(1L);
        user1.setUsername("xh3");
        user1.setPassword("password");
        user1.setBirthday(new Date());
        userList.add(user1);
        User user2 = new User();
        user2.setId(1L);
        user2.setUsername("xh2");
        user2.setPassword("password");
        user2.setBirthday(new Date());
        userList.add(user2);
        User user3 = new User();
        user3.setId(1L);
        user3.setUsername("xh1");
        user3.setPassword("password");
        user3.setBirthday(new Date());
        userList.add(user3);
        return userList;
    }

    /**
     * Spring mvc 会自动将参数塞进对象里
     * @param user 接受参数的对象
     * @return 返回结果
     */
    @GetMapping("/all")
    @JsonView(User.UserSimpleView.class)
    public ArrayList<User> queryAll(User user) {
        ArrayList<User> userList = new ArrayList<>();
        userList.add(user);
        return userList;
    }

    /**
     * 介绍获取 url 中的参数，正则的使用
     * 不适用正则就是 /{id} ，使用后里面的 id 匹配正则才可以获取参数，否则返回 400 状态
     * @param id
     * @return
     */
    @GetMapping("/{id:\\d+}")
    public User getInfo(@PathVariable Long id) {
        User user = new User();
        user.setUsername("tom");
        return user;
}

    /**
     * 使用 RequestBody 才能解析字符串，如果你传的是分开的 URL 参数而不是一个字符串 json，就可以不用
     * 通过 RequestBody 可以将请求体中的JSON字符串绑定到相应的bean上
     * Valid 用于校验，在实体类使用封装好的校验注解，也可以自定义校验
     * 可以使用 BindingResult 配合 Valid ，校验失败的信息都会放到它的里面，并且程序不会报错
     * @param user 用户实体类
     * @return 请求结果
     */
    @ApiOperation("用户添加服务")
    @PostMapping
    public User create(@Valid @RequestBody User user, BindingResult erros) {
        if (erros.hasErrors()) {
            erros.getAllErrors().forEach(err -> System.out.println(err.getDefaultMessage()));
        }
        user.setId(1L);
        return user;
    }

    /**
     * 功能描述 更新操作测试
     * @param user   更新的内容
     * @param errors 要跟在验证 Valid 的后面，才不是报错400
     * @param id     更新的id
     * @return com.xhl.shop.shopsecuritydemo.domain.User
     * @author 徐宏亮
     */
    @PutMapping("/{id:\\d+}")
    public User update(@Valid @RequestBody User user, BindingResult errors, @PathVariable Long id) {
        if (errors.hasErrors()) {
            errors.getAllErrors().forEach(
                    error -> {
                        FieldError fieldError = (FieldError) error;
                        System.out.println(fieldError.getField() + "：" + error.getDefaultMessage());
                    }
            );
        }
        user.setId(id);
        System.out.println(user.toString());
        return user;
    }

    @DeleteMapping("/{id:\\d+}")
    public void delete(@PathVariable Long id) {
        System.out.println(id);
    }

    /**
     * 异常处理
     * @param id id
     * @return
     */
    @GetMapping("/err/{id:\\d+}")
    public User getInfoErr(@PathVariable Long id) {
        //1. 直接抛出异常
        //throw new RuntimeException("用户名不存在");

        //2. 自定义异常，然后使用控制器异常监控类，进行返回特定的结果 ControllerExceptionHandler
        //throw new UserNotExistException(id);

        //3. 使用 Filter
        System.out.println("进入 getInfo 服务");
        User user = new User();
        user.setId(id);
        user.setUsername("tom");
        return user;
    }
}
